package com.zjhhsd.blackJack.controller;

import com.alibaba.fastjson.JSON;
import com.zjhhsd.blackJack.model.Card;
import com.zjhhsd.blackJack.util.CardUtil;
import com.zjhhsd.blackJack.util.RoomUtil;
import com.zjhhsd.blackJack.model.Result;
import com.zjhhsd.blackJack.model.RoomInfo;
import com.zjhhsd.blackJack.model.UserInfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import static com.zjhhsd.blackJack.util.RoomUtil.setDemandUser;

@Controller
public class MainController {

    public static ArrayList<String> roomLog = RoomUtil.roomLog;

    private static RoomInfo roomInfo = new RoomInfo();
    static{
        //应当在创建房间时创建一个RoomInfo对象，但是目前不设置此功能，所以在静态块中进行初始化
        roomInfo.setStatus("准备中");
        roomInfo.setBossName("");
        Map<String, UserInfo> map = new HashMap<>();
        roomInfo.setMap(map);
    }

    public static RoomInfo getRoomInfo() {
        return roomInfo;
    }

    @GetMapping("/log")
    @ResponseBody
    public Object Log(){
        return JSON.toJSONString(roomLog);
    }

    @PostMapping("/getLog")
    @ResponseBody
    public Object getLog(@RequestBody String logIndex){
        String substring = logIndex.substring(12, logIndex.length() - 1);
        int index = Integer.parseInt(substring);
        String result = "";
        int size = roomLog.size();
        for (int i = index; i < size; i++) {
            result += roomLog.get(i) + "<br>";
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("needClear", CardUtil.needClear);
        map.put("index",size);
        map.put("newLog",result);
        return map;
    }

    //每隔一段时间都会请求到这里，获取最新的房间信息进行刷新
    @PostMapping("/load")
    @ResponseBody
    public Object load(@RequestBody String username){//username标识是哪个用户发送的请求
        username = username.substring(13,username.length()-2);
        Map<String, UserInfo> map = roomInfo.getMap();
        roomInfo.setInGameCount(map.size());
        if(!roomInfo.getBossName().equals(username) && map.size() == 1 && map.get(username)!=null){
            //当前用户为唯一用户且不是庄家时，将其设置为庄家
            map.get(username).setBoss(true);//用户信息中设置当前用户为庄家
            roomInfo.setBossName(username);//房间信息中设置当前用户为庄家
            roomLog.add(username + "被设置为庄家");
        }
        if(roomInfo.getBossName().equals("") && map.size() > 1){//多个用户但是无庄家（在庄家退出时发生）
            synchronized (this){
                //避免重复修改 加锁
                if(roomInfo.getBossName().equals("")){//二次验证
                    map.get(username).setBoss(true);//用户信息中设置当前用户为房主
                    roomInfo.setBossName(username);//房间信息中设置当前用户为房主
                    roomLog.add(username + "被设置为庄家");
                }
            }
        }
        return roomInfo;
    }

    //开始游戏
    @PostMapping("/start")
    @ResponseBody
    public Object start(@RequestBody String username){//username标识是哪个用户发送的请求
        username = username.substring(13,username.length()-2);
        if("准备中".equals(roomInfo.getStatus()) && roomInfo.getBossName().equals(username)){
            roomLog.add("庄家" + username + "开启了游戏");
            roomInfo.setStatus("发牌中");
            CardUtil.initCardList();
            CardUtil.initUserCard(roomInfo);
            setDemandUser(roomInfo);
        }
        return roomInfo;
    }

    //庄家发牌给正在要牌的玩家
    @PostMapping("/deal")
    @ResponseBody
    public Object deal(){
        String demandName = roomInfo.getDemandName();
        CardUtil.deal(roomInfo,demandName);
        return roomInfo;
    }

    //闲家点击亮牌，展示自己所有的卡牌
    @PostMapping("/showAllCard")
    @ResponseBody
    public Object showAllCard(@RequestBody String username){//username标识是哪个用户发送的请求
        username = username.substring(13,username.length()-2);
        UserInfo userInfo = roomInfo.getMap().get(username);
        if(userInfo.getUnderCard1().getView()){
           //如果底牌已亮，则重复点击不执行后续动作
           return roomInfo;
        }
        userInfo.getUnderCard1().setView(true);
        userInfo.getUnderCard2().setView(true);
        roomLog.add("闲家" + username + "亮牌了！他什么牌型都不是，竟然明牌了！");
        if(userInfo.getFrontCard1() == null && CardUtil.score(userInfo) == 21){
            //构成杰克
            userInfo.setIdentity("杰克");
            userInfo.setCardCombo(1);
            roomLog.add("闲家" + username + "亮牌了！他的牌型是: 杰克!");
        }
        userInfo.setIdentity("亮牌");
        setDemandUser(roomInfo);
        return roomInfo;
    }

    //闲家点击停止要牌，轮换至下一个闲家要牌
    @PostMapping("/next")
    @ResponseBody
    public Object next(@RequestBody String username){//username标识是哪个用户发送的请求
        username = username.substring(13,username.length()-2);
        UserInfo userInfo = roomInfo.getMap().get(username);
        userInfo.setIdentity("停止要牌");
        roomLog.add("闲家" + username + "停止要牌了！");
        setDemandUser(roomInfo);
        return roomInfo;
    }

    //庄家点击进入开牌阶段
    @PostMapping("/openCard")
    @ResponseBody
    public Object openCard(@RequestBody String username){//username标识是哪个用户发送的请求
        username = username.substring(13,username.length()-2);
        String bossName = roomInfo.getBossName();
        roomLog.add("房间进入开牌阶段了！");
        if("等待开牌".equals(roomInfo.getStatus()) && bossName.equals(username)){
            roomInfo.setDemandName(username);
            roomInfo.setStatus("开牌中");
            UserInfo userInfo = roomInfo.getMap().get(bossName);
            userInfo.setIdentity("正在谋划开谁的牌");
        }
        return roomInfo;
    }

    //庄家开某人的牌
    @PostMapping("/kaipai")
    @ResponseBody
    public Result kaipai(@RequestBody String username){//username标识是哪个用户发送的请求
        username = username.substring(13,username.length()-2);
        UserInfo userInfo = roomInfo.getMap().get(username);
        userInfo.getUnderCard1().setView(true);
        userInfo.getUnderCard2().setView(true);
        String bossName = roomInfo.getBossName();
        return compare(roomInfo,userInfo,bossName);
    }

    //开始下一局
    @PostMapping("/restart")
    @ResponseBody
    public Object restart(){//username标识是哪个用户发送的请求
        roomLog.add("新的一局开始了");
        //重置房间信息
        roomInfo.setInGameCount(0);
        roomInfo.setStatus("准备中");
        roomInfo.setDemandName("");
        roomInfo.setClearStop("");
        resetUserMap(roomInfo);
        CardUtil.initCardList();
        CardUtil.needClear = true;
        return roomInfo;
    }

    //更换庄家
    @PostMapping("/changeBoss")
    @ResponseBody
    public Object changeBoss(@RequestBody String username){//username标识是哪个用户发送的请求
        roomInfo.getMap().get(roomInfo.getBossName()).setBoss(false);
        username = username.substring(13,username.length()-2);
        UserInfo bossInfo = roomInfo.getMap().get(username);
        roomInfo.setInGameCount(0);
        roomInfo.setStatus("准备中");
        roomInfo.setDemandName("");
        String bossName = bossInfo.getUsername();
        roomInfo.setBossName(bossName);
        roomLog.add("庄家把庄家更换给->" + bossName);
        bossInfo.setBoss(true);
        roomInfo.setClearStop("");
        resetUserMap(roomInfo);
        CardUtil.initCardList();
        CardUtil.needClear = true;
        return roomInfo;
    }

    private void resetUserMap(RoomInfo roomInfo) {
        Map<String, UserInfo> map = roomInfo.getMap();
        for (Map.Entry<String,UserInfo> entry : map.entrySet()) {
            UserInfo userInfo = entry.getValue();
            userInfo.setUnderCard1(null);
            userInfo.setUnderCard2(null);
            userInfo.setFrontCard1(null);
            userInfo.setFrontCard2(null);
            userInfo.setFrontCard3(null);
            userInfo.setIdentity("等待中");
            userInfo.setDemanded(false);
            userInfo.setOpened(false);
            userInfo.setOpened(false);
            userInfo.setCardCombo(0);
        }
    }


    private Result compare(RoomInfo roomInfo, UserInfo userInfo,String bossName){
        UserInfo bossInfo = roomInfo.getMap().get(bossName);
        Integer userScore = CardUtil.score(userInfo);
        Integer bossScore = CardUtil.score(bossInfo);
        System.out.println("bossScore = " + bossScore);
        System.out.println("userScore = " + userScore);
        Result result = new Result();
        if(userInfo.getCardCombo() > bossInfo.getCardCombo()){
            bossInfo.setIdentity("庄家妄图用普通牌去比五小龙");
            roomLog.add("庄家妄图用普通牌去比五小龙");
            return result;
        }
        result.setBossPoint(bossScore);
        result.setPlayerPoint(userScore);
        String username = userInfo.getUsername();
        if(userScore > 21){
            result.setWinnerName(bossName);
            result.setNextBoss(bossName);
            result.setStatus("闲家爆");
            userInfo.setIdentity("点数炸了");
            roomLog.add(username + "点数炸了,总点数" + userScore);
            return result;
        }
        if(bossScore > 21){
            result.setWinnerName(username);
            result.setNextBoss(username);
            result.setStatus("庄家爆");
            userInfo.setIdentity("给庄家弄炸了");
            bossInfo.setIdentity("点数炸了");
            roomLog.add("庄家点数炸了,总点数" + bossScore);
            return result;
        }
        if(userScore > bossScore){
            result.setWinnerName(username);
            result.setNextBoss(username);
            result.setStatus("给庄家干了！");
            userInfo.setIdentity("点数大于庄家");
            roomLog.add(username + "总点数" + userScore + ",胜于庄家");
            bossInfo.setIdentity("刚开了" + username + "的牌，输了");
        }else {
            result.setWinnerName(bossName);
            result.setNextBoss(bossName);
            result.setStatus("被庄家干了！");
            userInfo.setIdentity("比点数输给庄家");
            roomLog.add(username + "总点数" + userScore + ",负于庄家");
            bossInfo.setIdentity("刚开了" + username + "的牌，赢了");
        }
        return result;
    }

}
